package net.weamor.interfaces.service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.weamor.interfaces.ServiceConfig;
import net.weamor.interfaces.factory.param.DefaultParam;
import net.weamor.interfaces.factory.param.Md5Param;
import net.weamor.interfaces.factory.param.ParamFactory;
import net.weamor.interfaces.factory.param.TimeParam;
import net.weamor.interfaces.factory.param.UrlEncoderParam;
import net.weamor.interfaces.global.GlobalVar;
import net.weamor.interfaces.pojo.CertificateBean;
import net.weamor.interfaces.pojo.Param;
import net.weamor.interfaces.pojo.RequestObject;
import net.weamor.interfaces.pojo.RequestParam;
import net.weamor.interfaces.pojo.config.ClassBean;
import net.weamor.interfaces.pojo.config.HostBean;
import net.weamor.interfaces.pojo.config.ThirdBean;
import net.weamor.interfaces.utils.DataKit;
import net.weamor.interfaces.utils.GsonKit;
import net.weamor.interfaces.utils.HttpKit;
import net.weamor.interfaces.utils.HttpsKit;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;



/** 
 * @ClassName HttpOperate  
 * @Description Https 请求数据对象操作 
 *   
 */
public class RequestService {
	private static Map<String, ThirdBean> configMap = ServiceConfig.configMap;

	private static Logger logger = LoggerFactory.getLogger(RequestService.class);
	

	/**
	 * 根据方法拿到相应的url地址
	 * @Title: dealWithUrl 
	 * @Description: 根据方法拿到相应的url地址
	 * @param pro
	 * @param method
	 * @return 参数说明
	 * @return String    返回类型
	 */
	public static String dealWithUrl(String pro, String method, String url) {
		String realReqUrl = "";
		if (DataKit.isNotEmpty(url)) {
			realReqUrl = url;
		} else {
			// 拿到地址
			List<HostBean> hosts = configMap.get(pro).getHosts();
			for (int i = 0; i < hosts.size(); i++) {
				String configMethod = hosts.get(i).getKey();
				if (method.equals(configMethod)) {
					realReqUrl = hosts.get(i).getUrl();
					break;
				}
			}
		}
		return realReqUrl;
	}
	
	/**
	 * 处理url 
	 * @Title: dealWithUrl  传入requestParam类
	 * @Description: 处理url  
	 * @param requestParam
	 * @return 参数说明
	 * @return String    返回类型
	 */
	public static String dealWithUrl(RequestObject requestParam){
		String pro = requestParam.getPro();
		String method = requestParam.getMethod();
		return dealWithUrl(pro, method, "");
	}

	/**
	 * 拿到类的全称
	 * @Title: getFullName 
	 * @return String    返回类型
	 */
	public static String getFullName(String pro, String key) {
		// 拿到地址
		List<ClassBean> classs = configMap.get(pro)
				.getClasss();
		for (int i = 0; i < classs.size(); i++) {
			String configMethod = classs.get(i).getKey();
			if (key.equals(configMethod)) {
				return classs.get(i).getForName();
			}
		}
		return "";
	}

	/**
	 * 处理参数 多个param
	 * @Title: dealWithParam 
	 * @Description: 处理参数
	 * @param jsonParam 参数说明
	 * @return void    返回类型
	 * @throws Exception 
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> dealWithParams(String param,
			String pro,String paramStyle) throws Exception {
		// 解析param
		Map<String, Object> argMap = new HashMap<String, Object>();
		
		if ("param".equalsIgnoreCase(paramStyle) || "json".equalsIgnoreCase(paramStyle)
				|| "xml".equalsIgnoreCase(paramStyle) || "".equalsIgnoreCase(paramStyle)
				|| null == paramStyle) {
			//param集合的标识为[ 在第一位
			if (param.indexOf("[") == 0) {
				List<Param> params = GsonKit.getJsonToParam(param);
				for (int i = 0; i < params.size(); i++) {
					argMap.putAll(dealWithParam(params.get(i), pro));
				}
			} else {
				Param params = GsonKit.getJson(param, Param.class);
				argMap.putAll(dealWithParam(params, pro));
			}
			
		} else if("map".equalsIgnoreCase(paramStyle)){
			argMap = GsonKit.getJson(param, Map.class);

		} else if("string".equalsIgnoreCase(paramStyle)){
			argMap.put("param", param);
		}
		return argMap;
	}
	
	/**
	 * 处理参数 
	 * @Title: dealWithParams 
	 * @Description:处理参数  传入requestParam类
	 * @param requestParam
	 * @return
	 * @throws Exception 参数说明
	 * @return Map<String,Object>    返回类型
	 */
	public static Map<String, Object> dealWithParams(RequestObject requestParam) throws Exception{
		String pro = requestParam.getPro();
		String paramStyle = requestParam.getParamstyle();
		String param = requestParam.getParam();
		return dealWithParams(param, pro, paramStyle);
	}

	/**
	 * 处理参数 单个param
	 * @Title: dealWithParam 
	 * @Description: 处理参数 单个param
	 * @param param
	 * @param pro
	 * @return
	 * @throws Exception 参数说明
	 * @return Map<String,String>    返回类型
	 */
	private static Map<String, Object> dealWithParam(Param param, String pro)
			throws Exception {
		String paramName = param.getName();
		String paramOprate = param.getOperate();
		// 解析param
		Map<String, Object> argMap = new HashMap<String, Object>();

		ParamFactory paramFactory = null;

		if (GlobalVar.PARAM_MD5.equals(paramOprate)) {
			paramFactory = new Md5Param();
		} else if (GlobalVar.PARAM_DEFAULT.equals(paramOprate)) {
			paramFactory = new DefaultParam();
		} else if (GlobalVar.PARAM_TIME.equals(paramOprate)) {
			paramFactory = new TimeParam();
		} else if (GlobalVar.PARAM_URLENCODER.equals(paramOprate)) {
			paramFactory = new UrlEncoderParam();
		} 
		
		Object paramValue = param.getValue();
		if (paramFactory != null) {
			paramValue = paramFactory.operate(param, pro);
		}

		argMap.put(paramName, paramValue);
		return argMap;
	}

	/**
	 * 发起普通的http请求
	 * @Title: doRequest 
	 * @Description:发起普通的http请求
	 * @param requestParam
	 * @param reqStyle
	 * @return
	 * @throws NoSuchFieldException
	 * @throws SecurityException
	 * @throws UnsupportedEncodingException 参数说明
	 * @return Map<String,Object>    返回类型
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> doRequest(RequestParam requestParam,String reqStyle)
			throws NoSuchFieldException, SecurityException,
			UnsupportedEncodingException {
		// 参数map和返回map
		Map<String, Object> retMap = new HashMap<String, Object>();
		Map<String, String> headMap = new HashMap<String, String>();
		String retData = "";
		String uniqueId = requestParam.getReqId();
		String reqEncoding = requestParam.getReqEncoding();
		String url = requestParam.getUrl();
		
		if (StringUtils.isEmpty(reqEncoding)) {
			reqEncoding = GlobalVar.DEFAULT_CHARSET;
		}
		
		//处理参数
		String jsonOrXml = "";
		if ("string".equalsIgnoreCase(requestParam.getParamstyle())) {
			jsonOrXml = (String) requestParam.getArgMap().get("param");
		}
	
		if (DataKit.isNotEmpty(requestParam.getHead())) {
			headMap = GsonKit.getJson(requestParam.getHead(), Map.class);
		}
	
		// 进行请求
		HttpResponse httpResponse = RequestService.doReqByStyle(url, reqStyle,
				requestParam.getArgMap(), headMap, jsonOrXml,reqEncoding);
		int statusCode = httpResponse.getStatusLine().getStatusCode();
	
		try {
			retData = EntityUtils.toString(httpResponse.getEntity(), reqEncoding);
			logger.info("{} Http请求获得的返回值原始编码:" + retData, uniqueId);
		} catch (ParseException | IOException e) {
			logger.error("#E {} Http请求发生了异常:" + e.getMessage(), uniqueId);
		}
	
		retMap.put("json", retData);
		retMap.put("statusCode", statusCode + "");
		return retMap;
	}
	
	/**
	 * 根据Post还是Get进行分类请求
	 * @Title: doReqByStyle 
	 * @Description: 根据Post还是Get进行分类请求
	 * @return HttpResponse    返回类型
	 */
	private static HttpResponse doReqByStyle(String url, String methodStyle,
			Map<String, Object> argMap, Map<String, String> headMap, String json,String reqEncoding) {
		// 进行请求
		HttpResponse httpResponse = null;
		boolean isSsl = false;
		if (url != null) {
			if (url.contains(GlobalVar.HTTPS)) {
				isSsl = true;
			}
		}

		if (GlobalVar.HTTP_POST.equals(methodStyle)) {
			httpResponse = HttpKit.getInstance(isSsl).doPost(url, null,
					argMap, headMap, json,reqEncoding);
		} else {
			httpResponse = HttpKit.getInstance(isSsl).doGet(url, argMap,
					headMap);
		}

		return httpResponse;
	}
	
	/**
	 * 请求双向方法
	 * @Title: doRequestBoth 
	 * @param certificateBean
	 * @param requestParam
	 * @return
	 * @throws NoSuchFieldException
	 * @throws SecurityException
	 * @throws UnsupportedEncodingException 参数说明
	 * @return Map<String,Object>    返回类型
	 */
	public static String doRequestBoth(CertificateBean certificateBean,
			RequestParam requestParam) {
		String reqEncoding = requestParam.getReqEncoding();
		
		if (StringUtils.isEmpty(reqEncoding)) {
			reqEncoding = GlobalVar.DEFAULT_CHARSET;
		}
		String responseStr = "";
		
		try {
			responseStr = HttpsKit.httpsRequest(certificateBean, requestParam, "");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return responseStr;
	}

}
